home *** CD-ROM | disk | FTP | other *** search
/ MacGames Sampler / PHT MacGames Bundle.iso / MacSource Folder / Samples from the CD / C and C++ / Gnuplot 3.5 for Macintosh / SOURCES 3.5 / plot.c < prev    next >
C/C++ Source or Header  |  1993-11-12  |  14KB  |  536 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: plot.c%v 3.50.1.8 1993/07/27 05:37:15 woo Exp $";
  3. #endif
  4.  
  5.  
  6. /* GNUPLOT - plot.c */
  7. /*
  8.  * Copyright (C) 1986 - 1993   Thomas Williams, Colin Kelley
  9.  *
  10.  * Permission to use, copy, and distribute this software and its
  11.  * documentation for any purpose with or without fee is hereby granted, 
  12.  * provided that the above copyright notice appear in all copies and 
  13.  * that both that copyright notice and this permission notice appear 
  14.  * in supporting documentation.
  15.  *
  16.  * Permission to modify the software is granted, but not the right to
  17.  * distribute the modified code.  Modifications are to be distributed 
  18.  * as patches to released version.
  19.  *  
  20.  * This software is provided "as is" without express or implied warranty.
  21.  * 
  22.  *
  23.  * AUTHORS
  24.  * 
  25.  *   Original Software:
  26.  *     Thomas Williams,  Colin Kelley.
  27.  * 
  28.  *   Gnuplot 2.0 additions:
  29.  *       Russell Lang, Dave Kotz, John Campbell.
  30.  *
  31.  *   Gnuplot 3.0 additions:
  32.  *       Gershon Elber and many others.
  33.  * 
  34.  * There is a mailing list for gnuplot users. Note, however, that the
  35.  * newsgroup 
  36.  *    comp.graphics.gnuplot 
  37.  * is identical to the mailing list (they
  38.  * both carry the same set of messages). We prefer that you read the
  39.  * messages through that newsgroup, to subscribing to the mailing list.
  40.  * (If you can read that newsgroup, and are already on the mailing list,
  41.  * please send a message info-gnuplot-request@dartmouth.edu, asking to be
  42.  * removed from the mailing list.)
  43.  *
  44.  * The address for mailing to list members is
  45.  *       info-gnuplot@dartmouth.edu
  46.  * and for mailing administrative requests is 
  47.  *       info-gnuplot-request@dartmouth.edu
  48.  * The mailing list for bug reports is 
  49.  *       bug-gnuplot@dartmouth.edu
  50.  * The list of those interested in beta-test versions is
  51.  *       info-gnuplot-beta@dartmouth.edu
  52.  */
  53.  
  54. #include <stdio.h>
  55. #include <setjmp.h>
  56. #include <signal.h>
  57. #ifdef XPG3_LOCALE
  58. #include <locale.h>
  59. #endif
  60. #include "plot.h"
  61. #ifdef THINK_C
  62. #include "tout_protos.h"
  63. #endif
  64.  
  65. #include "setshow.h"
  66. #if defined(MSDOS) || defined(DOS386)
  67. #include <io.h>
  68. #endif
  69. #ifdef vms
  70. #include <unixio.h>
  71. #include <smgdef.h>
  72. extern int vms_vkid;
  73. extern smg$create_virtual_keyboard();
  74. unsigned int status[2] = {1, 0};
  75. #endif
  76. #ifdef AMIGA_SC_6_1
  77. #include <proto/dos.h>
  78. #endif
  79.  
  80. #ifdef _Windows
  81. #include <windows.h>
  82. #ifndef SIGINT
  83. #define SIGINT 2    /* for MSC */
  84. #endif
  85. #else
  86. # ifdef __TURBOC__
  87. # include <graphics.h>
  88. # endif
  89. #endif
  90.  
  91. #ifndef AMIGA_SC_6_1
  92. extern char *getenv(),*strcat(),*strcpy(),*strncpy();
  93. #endif /* !AMIGA_SC_6_1 */
  94.  
  95. extern char input_line[];
  96. extern int c_token;
  97. extern FILE *outfile;
  98. extern int term;
  99.  
  100. TBOOLEAN interactive = TRUE;    /* FALSE if stdin not a terminal */
  101. TBOOLEAN noinputfiles = TRUE;    /* FALSE if there are script files */
  102. char *infile_name = NULL;    /* name of command file; NULL if terminal */
  103.  
  104. #ifndef STDOUT
  105. #define STDOUT 1
  106. #endif
  107.  
  108. #ifdef _Windows
  109. jmp_buf far env;
  110. #else
  111. jmp_buf env;
  112. #endif
  113.  
  114. struct value *Ginteger(),*Gcomplex();
  115.  
  116.  
  117. extern f_push(),f_pushc(),f_pushd1(),f_pushd2(),f_pushd(),f_call(),f_calln(),
  118.     f_lnot(),f_bnot(),f_uminus(),f_lor(),f_land(),f_bor(),f_xor(),
  119.     f_band(),f_eq(),f_ne(),f_gt(),f_lt(),
  120.     f_ge(),f_le(),f_plus(),f_minus(),f_mult(),f_div(),f_mod(),f_power(),
  121.     f_factorial(),f_bool(),f_jump(),f_jumpz(),f_jumpnz(),f_jtern();
  122.  
  123. extern f_real(),f_imag(),f_arg(),f_conjg(),f_sin(),f_cos(),f_tan(),f_asin(),
  124.     f_acos(),f_atan(),f_sinh(),f_cosh(),f_tanh(),f_int(),f_abs(),f_sgn(),
  125.     f_sqrt(),f_exp(),f_log10(),f_log(),f_besj0(),f_besj1(),f_besy0(),f_besy1(),
  126.     f_erf(), f_erfc(), f_gamma(), f_lgamma(), f_ibeta(), f_igamma(), f_rand(),
  127.     f_floor(),f_ceil(),
  128.     f_normal(), f_inverse_erf(), f_inverse_normal();   /* XXX - JG */
  129.  
  130.  
  131. struct ft_entry GPFAR ft[] = {    /* built-in function table */
  132.  
  133. /* internal functions: */
  134.     {"push", f_push},    {"pushc", f_pushc},
  135.     {"pushd1", f_pushd1},    {"pushd2", f_pushd2},    {"pushd", f_pushd},
  136.     {"call", f_call},    {"calln", f_calln},    {"lnot", f_lnot},
  137.     {"bnot", f_bnot},    {"uminus", f_uminus},    {"lor", f_lor},
  138.     {"land", f_land},    {"bor", f_bor},        {"xor", f_xor},
  139.     {"band", f_band},    {"eq", f_eq},        {"ne", f_ne},
  140.     {"gt", f_gt},        {"lt", f_lt},        {"ge", f_ge},
  141.     {"le", f_le},        {"plus", f_plus},    {"minus", f_minus},
  142.     {"mult", f_mult},    {"div", f_div},        {"mod", f_mod},
  143.     {"power", f_power}, {"factorial", f_factorial},
  144.     {"bool", f_bool},    {"jump", f_jump},    {"jumpz", f_jumpz},
  145.     {"jumpnz",f_jumpnz},{"jtern", f_jtern},
  146.  
  147. /* standard functions: */
  148.     {"real", f_real},    {"imag", f_imag},    {"arg", f_arg},
  149.     {"conjg", f_conjg}, {"sin", f_sin},        {"cos", f_cos},
  150.     {"tan", f_tan},        {"asin", f_asin},    {"acos", f_acos},
  151.     {"atan", f_atan},    {"sinh", f_sinh},    {"cosh", f_cosh},
  152.     {"tanh", f_tanh},    {"int", f_int},        {"abs", f_abs},
  153.     {"sgn", f_sgn},        {"sqrt", f_sqrt},    {"exp", f_exp},
  154.     {"log10", f_log10},    {"log", f_log},        {"besj0", f_besj0},
  155.     {"besj1", f_besj1},    {"besy0", f_besy0},    {"besy1", f_besy1},
  156.         {"erf", f_erf},         {"erfc", f_erfc},       {"gamma", f_gamma},     {"lgamma", f_lgamma},
  157.         {"ibeta", f_ibeta},     {"igamma", f_igamma},   {"rand", f_rand},
  158.         {"floor", f_floor},     {"ceil", f_ceil},
  159.  
  160.     {"norm",        f_normal},              /* XXX-JG */
  161.     {"inverf",      f_inverse_erf},         /* XXX-JG */
  162.     {"invnorm",     f_inverse_normal},      /* XXX-JG */
  163.  
  164.     {NULL, NULL}
  165. };
  166.  
  167. static struct udvt_entry udv_pi = {NULL, "pi",FALSE};
  168.                                     /* first in linked list */
  169. struct udvt_entry *first_udv = &udv_pi;
  170. struct udft_entry *first_udf = NULL;
  171.  
  172.  
  173.  
  174. #ifdef vms
  175.  
  176. #define HOME "sys$login:"
  177. #elif  THINK_C
  178. #define HOME ":"
  179.  
  180. #else /* vms */
  181. #if defined(MSDOS) ||  defined(AMIGA_AC_5) || defined(AMIGA_SC_6_1) || defined(ATARI) || defined(OS2) || defined(_Windows) || defined(DOS386)
  182.  
  183. #define HOME "GNUPLOT"
  184.  
  185. #else /* MSDOS || AMIGA || ATARI || OS2 || _Windows || defined(DOS386)*/
  186.  
  187. #define HOME "HOME"
  188.  
  189. #endif /* MSDOS || AMIGA || ATARI || OS2 || _Windows || defined(DOS386)*/
  190. #endif /* vms */
  191.  
  192. #if defined(unix) || defined(AMIGA_AC_5) || defined(AMIGA_SC_6_1)
  193. #define PLOTRC ".gnuplot"
  194. #elif THINK_C
  195. #define PLOTRC ":gnuplot.ini"
  196. #else /* AMIGA || unix || THINK_C */
  197. #define PLOTRC "gnuplot.ini"
  198. #endif /* AMIGA || unix */
  199.  
  200. #if defined (__TURBOC__) || defined (__PUREC__)
  201. void tc_interrupt()
  202. #else
  203. #ifdef __ZTC__
  204. void ztc_interrupt()
  205. #else
  206. #if defined( _CRAY ) || defined( sgi ) || defined( __alpha )
  207. void inter(an_int)
  208. int an_int;
  209. #else
  210. #if defined( NEXT ) || defined( OS2 ) || defined( VMS )
  211. void inter(int an_int)
  212. #else
  213. #ifdef sgi
  214. void inter(int sig, int code, struct sigcontext *sc)
  215. #else
  216. #if defined(SOLARIS)
  217. void inter()
  218. #else
  219. inter()
  220. #endif
  221. #endif
  222. #endif
  223. #endif
  224. #endif
  225. #endif
  226. {
  227. #if defined (MSDOS) || defined(_Windows) || (defined (ATARI) && defined(__PUREC__)) || defined(DOS386)
  228. #if defined (__TURBOC__) || defined (__PUREC__)
  229. #ifndef DOSX286
  230.     (void) signal(SIGINT, tc_interrupt);
  231. #endif
  232. #else
  233. #ifdef __ZTC__
  234.    (void) signal(SIGINT, ztc_interrupt);
  235. #else
  236. #ifdef __EMX__
  237.     (void) signal(SIGINT, (void *)inter);
  238. #else
  239. #ifdef DJGPP
  240.     (void) signal(SIGINT, (SignalHandler)inter);
  241. #else
  242. #if defined __MSC__
  243.     (void) signal(SIGINT, inter);
  244. #endif    /* __MSC__ */
  245.  
  246. #endif    /* DJGPP */
  247. #endif  /* __EMX__ */
  248. #endif    /* ZTC */
  249. #endif  /* __TURBOC__ */
  250.  
  251. #else  /* MSDOS */
  252. #ifdef OS2
  253.     (void) signal(an_int, SIG_ACK);
  254. #elif THINK_C
  255.     (void) signal(SIGINT, (__sig_func) inter);
  256. #else
  257.     (void) signal(SIGINT, inter);
  258. #endif  /* OS2 */
  259. #endif  /* MSDOS */
  260. #ifndef DOSX286
  261.     (void) signal(SIGFPE, SIG_DFL);    /* turn off FPE trapping */
  262. #endif
  263.     if (term && term_init)
  264.         (*term_tbl[term].text)();    /* hopefully reset text mode */
  265.     (void) fflush(outfile);
  266.     (void) putc('\n',stderr);
  267.     longjmp(env, TRUE);        /* return to prompt */
  268. }
  269.  
  270.  
  271. #ifdef _Windows
  272. gnu_main(argc, argv)
  273. #elif THINK_C
  274. #include <console.h>
  275. main()
  276. {
  277.     int argc;
  278.     char **argv;
  279.  
  280.   argc=ccommand(&argv);
  281.   unix_main(argc,argv);
  282. }
  283. unix_main(argc,argv)
  284. #else
  285. main(argc, argv)
  286. #endif
  287.     int argc;
  288.     char **argv;
  289. {
  290. #ifdef XPG3_LOCALE
  291.     (void) setlocale(LC_CTYPE, "");
  292. #endif
  293. /* Register the Borland Graphics Interface drivers. If they have been */
  294. /* included by the linker.                                            */
  295.  
  296. #ifndef DOSX286
  297. #ifndef _Windows
  298. #if defined (__TURBOC__) && defined (MSDOS)
  299. registerfarbgidriver(EGAVGA_driver_far);
  300. registerfarbgidriver(CGA_driver_far);
  301. registerfarbgidriver(Herc_driver_far);
  302. registerfarbgidriver(ATT_driver_far);
  303. # endif
  304. #endif
  305. #endif
  306. #ifdef X11
  307.      { int n = X11_args(argc, argv); argv += n; argc -= n; }
  308. #endif 
  309.  
  310. #ifdef apollo
  311.     apollo_pfm_catch();
  312. #endif
  313.  
  314.     setbuf(stderr,(char *)NULL);
  315. #ifdef UNIX
  316.     setlinebuf(stdout);
  317. #endif
  318.     outfile = stdout;
  319.     (void) Gcomplex(&udv_pi.udv_value, Pi, 0.0);
  320.  
  321.      interactive = FALSE;
  322.      init_terminal();        /* can set term type if it likes */
  323.  
  324. #ifdef AMIGA_SC_6_1
  325.      if (IsInteractive(Input()) == DOSTRUE) interactive = TRUE;
  326.      else interactive = FALSE;
  327. #else
  328. #if defined(__MSC__) && defined(_Windows)
  329.      interactive = TRUE;
  330. #else
  331.      interactive = isatty(fileno(stdin));
  332. #endif
  333. #endif
  334.      if (argc > 1)
  335.       interactive = noinputfiles = FALSE;
  336.      else
  337.       noinputfiles = TRUE;
  338.  
  339.      if (interactive)
  340.       show_version();
  341. #ifdef vms   /* initialise screen management routines for command recall */
  342.           if (status[1] = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL)
  343.                done(status[1]);
  344. #endif
  345.  
  346. #undef DEBUG_THINK
  347. #ifndef DEBUG_THINK
  348.     if (!setjmp(env)) {
  349.         /* first time */
  350.         interrupt_setup();
  351.         load_rcfile();
  352.  
  353.         if (interactive && term != 0)    /* not unknown */
  354.          fprintf(stderr, "\nTerminal type set to '%s'\n", 
  355.                 term_tbl[term].name);
  356.     } else {
  357.         /* come back here from int_error() */
  358.         load_file_error();    /* if we were in load_file(), cleanup */
  359. #ifdef _Windows
  360.     SetCursor(LoadCursor((HINSTANCE)NULL, IDC_ARROW));
  361. #endif
  362. #ifdef vms
  363.         /* after catching interrupt */
  364.         /* VAX stuffs up stdout on SIGINT while writing to stdout,
  365.           so reopen stdout. */
  366.         if (outfile == stdout) {
  367.            if ( (stdout = freopen("SYS$OUTPUT","w",stdout))  == NULL) {
  368.               /* couldn't reopen it so try opening it instead */
  369.               if ( (stdout = fopen("SYS$OUTPUT","w"))  == NULL) {
  370.                  /* don't use int_error here - causes infinite loop! */
  371.                  fprintf(stderr,"Error opening SYS$OUTPUT as stdout\n");
  372.               }
  373.            }
  374.            outfile = stdout;
  375.         }
  376. #endif                    /* VMS */
  377.         if (!interactive && !noinputfiles) {
  378.             if (term && term_init)
  379.                 (*term_tbl[term].reset)();
  380. #ifdef vms
  381.             vms_reset();
  382. #endif
  383.             return(IO_ERROR);    /* exit on non-interactive error */
  384.          }
  385.     }
  386. #endif /* DEBUG_THINK */
  387.  
  388. #ifdef DEBUG_THINK
  389.         if (interactive && term != 0)    /* not unknown */
  390.          fprintf(stderr, "\nTerminal type set to '%s'\n", 
  391.                 term_tbl[term].name);
  392. #endif
  393.  
  394.      if (argc > 1) {
  395.         /* load filenames given as arguments */
  396.         while (--argc > 0) {
  397.            ++argv;
  398.            c_token = NO_CARET; /* in case of file not found */
  399.            load_file(fopen(*argv,"r"), *argv);    
  400.         }
  401.     } else {
  402.         /* take commands from stdin */
  403.         while(!com_line());
  404.     }
  405.  
  406.     if (term && term_init)
  407.         (*term_tbl[term].reset)();
  408. #ifdef vms
  409.     vms_reset();
  410. #endif
  411.     return(IO_SUCCESS);
  412. }
  413.  
  414. #if defined(ATARI) && defined(__PUREC__)
  415. #include <math.h>
  416. int purec_matherr(struct exception *e)
  417. {    char *c;
  418.     switch (e->type) {
  419.         case DOMAIN:    c = "domain error"; break;
  420.         case SING  :    c = "argument singularity"; break;
  421.         case OVERFLOW:  c = "overflow range"; break;
  422.         case UNDERFLOW: c = "underflow range"; break;
  423.         default:        c = "(unknown error"; break;
  424.     }
  425.     fprintf(stderr, "math exception : %s\n", c);
  426.     fprintf(stderr, "    name : %s\n", e->name);
  427.     fprintf(stderr, "    arg 1: %e\n", e->arg1);
  428.     fprintf(stderr, "    arg 2: %e\n", e->arg2);
  429.     fprintf(stderr, "    ret  : %e\n", e->retval);
  430.     return 1;
  431. }
  432. #endif
  433.  
  434. /* Set up to catch interrupts */
  435. interrupt_setup()
  436. {
  437. #if defined (MSDOS) || defined(_Windows) || (defined (ATARI) && defined(__PUREC__)) || defined(DOS386)
  438. #ifdef __PUREC__
  439.     setmatherr(purec_matherr);
  440. #endif
  441. #if defined (__TURBOC__) || defined (__PUREC__)
  442. #if !defined(DOSX286) && !defined(BROKEN_SIGINT)
  443.         (void) signal(SIGINT, tc_interrupt);    /* go there on interrupt char */
  444. #endif
  445. #else
  446. #ifdef __ZTC__
  447.         (void) signal(SIGINT, ztc_interrupt);
  448. #else
  449. #ifdef __EMX__
  450.         (void) signal(SIGINT, (void *)inter);    /* go there on interrupt char */
  451. #else
  452. #ifdef DJGPP
  453.         (void) signal(SIGINT, (SignalHandler)inter);    /* go there on interrupt char */
  454. #else
  455.                (void) signal(SIGINT, inter);
  456. #endif
  457. #endif
  458. #endif
  459. #endif
  460. #else /* MSDOS || THIN_C */
  461. #ifdef THINK_C 
  462.     (void) signal(SIGINT, (__sig_func) inter);
  463. #else /* MSDOS */
  464.         (void) signal(SIGINT, inter);    /* go there on interrupt char */
  465. #endif
  466. #endif /* MSDOS */
  467. }
  468.  
  469.  
  470. /* Look for a gnuplot start-up file */
  471. load_rcfile()
  472. {
  473.     register FILE *plotrc;
  474.     char home[80]; 
  475.     char rcfile[sizeof(PLOTRC)+80];
  476.  
  477.     /* Look for a gnuplot init file in . or home directory */
  478. #ifdef vms
  479.     (void) strcpy(home,HOME);
  480. #elif THINK_C
  481.     (void) strcat(strcpy(home,getenv(HOME)),":");
  482. #else /* vms */
  483.     char *tmp_home=getenv(HOME);
  484.     char *p;    /* points to last char in home path, or to \0, if none */
  485.     char c='\0';/* character that should be added, or \0, if none */
  486.  
  487.  
  488.     if(tmp_home) {
  489.         strcpy(home,tmp_home);
  490.     if( strlen(home) ) p = &home[strlen(home)-1];
  491.     else           p = home;
  492. #if defined(MSDOS) || defined(ATARI) || defined( OS2 ) || defined(_Windows) || defined(DOS386)
  493.     if( *p!='\\' && *p!='\0' ) c='\\';
  494. #else
  495. #if defined(AMIGA_AC_5)
  496.     if( *p!='/' && *p!=':' && *p!='\0' ) c='/';
  497. #else /* that leaves unix */
  498.     c='/';
  499. #endif
  500. #endif
  501.     if(c) {
  502.         if(*p) p++;
  503.         *p++=c;
  504.         *p='\0';
  505.     }
  506.     }
  507. #endif /* vms */
  508.  
  509. #ifdef NOCWDRC
  510.     /* inhibit check of init file in current directory for security reasons */
  511.     {
  512. #else
  513.     (void) strcpy(rcfile, PLOTRC);
  514.     plotrc = fopen(rcfile,"r");
  515.     if (plotrc == (FILE *)NULL) {
  516. #endif
  517.  
  518. #ifdef THINK_C
  519.        (void) sprintf(rcfile, "%s%s", home, PLOTRC);
  520.        plotrc = fopen(rcfile,"r");
  521. #else /* THINK_C */
  522. #ifndef vms
  523.     if( tmp_home ) {
  524. #endif
  525.        (void) sprintf(rcfile, "%s%s", home, PLOTRC);
  526.        plotrc = fopen(rcfile,"r");
  527. #ifndef vms
  528.     } else
  529.         plotrc=NULL;
  530. #endif
  531. #endif    /* THINK_C */
  532.     }
  533.     if (plotrc)
  534.      load_file(plotrc, rcfile);
  535. }
  536.